/** @file gpio-target.c 
 * Implementiert die GPIO-Schnittstelle auf dem Zielsystem (LCV-Board) 
 * 
 * @author Daniel Kummer, Sebastian Kummer
 * @date Donnerstag, Dezember 12, 2007
 * @version 1.0
 */

#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/ioctl.h>
#include <errno.h>
#include <unistd.h> 
#include <string.h>
#include <stdio.h>
#include "pflags.h"
#include "gpio.h"
#include "gpio-port-config.h"
#include "log.h"

 char lcv_gpio_read(unsigned char port)
{
	int in_port;	
	int ret;
	char in_read[2]; 
	/* Es ist notwendig, jeweils zwei Einträge zu lesen um korrekte Werte zu erhalten, wir wissen nicht warum*/

	if (port > gpio_in_ports_cnt) {
		return ERROR_ILLEGAL_PORT;
	} 	
	
	in_port = open(gpio_in[port],O_RDONLY,0);
		
	if (in_port == -1) {
		return ERROR;
	}
	
	ret = ioctl(in_port, SET_FIO_DIR, INPUT);	
	ret = ioctl(in_port, SET_FIO_INEN, INPUT_ENABLE);
	/* Reagiere nicht auf Flanken, sondern auf Level*/
	ret = ioctl(in_port, SET_FIO_EDGE, LEVEL);

	read(in_port, in_read,2);

	if (in_read[0] == '1') {
		ret = 1;
	} else {
		ret = 0;
	}
	close(in_port);
	return ret;
}

char lcv_gpio_write(unsigned char port, unsigned char value)
{	
	int out_port;	
	int ret;
	char* val;
	
	if (port > gpio_out_ports_cnt) {
		return ERROR_ILLEGAL_PORT;
	} 	

	/* Nur 0 und 1 als Werte zulassen */
	switch (value) {
		case 0:
			val = "0";		
			break;
		case 1:
			val = "1";
			break;
		default:
			return ERROR_ILLEGAL_VALUE;
	}
		
	out_port = open(gpio_out[port], O_RDWR, 0); 
	
	if(out_port < 0) {
		char log_entry[256];
		sprintf (log_entry, "Could not write GPIO Port %u", port);
		lcv_log_warning(log_entry, __FUNCTION__);
		return ERROR;
	}

	/* Port Eigenschaften setzen */	
	ret = ioctl(out_port, SET_FIO_DIR, OUTPUT);
	ret = ioctl(out_port, SET_FIO_INEN, INPUT_ENABLE);

	write(out_port,val,sizeof(val)); 
	usleep(1000); /* Zum Sicherstellen das der Port auch wirklich geschrieben wurde */
	close(out_port);
	
	return TRUE;
}


void lcv_gpio_simulate_input(unsigned char port, unsigned char value)
{
	
}

void lcv_gpio_simulate_output(void (*handler)(unsigned char port, unsigned char value))
{
	
}
